<?php
/**
 *	Copyright (c) TeamFlamingo And gray 2004-2010
 *	www.world-editor.com / www.i-gray.cn
 *
 *	[ WARNING!!! ] This is a freeware!
 *	[ WARNING!!! ] But, You MUST get author's authorization before using it!
 *
 *	Name : xnApi.core.php / Development Code Evolve
 *	Created / Modify : 2010-5-6 / 2010-5-7
 */

	interface	xnFriends
	{
		public	function	get( $format = 'XML', $page = '0', $count = '500' );
		public	function	getFriends( $format = 'XML', $page = '0', $count = '500' );
		public	function	areFriends( $uids1, $uids2 = false, $format = 'XML' );
		public	function	getAppFriends( $format = 'XML', $fields = false );
	}

	interface	xnUsers
	{
		public	function	getInfo( $uids, $format = 'XML', $fields = false, $sessionKey = false );
		public	function	isAppUser( $format = 'XML', $uid = false );
		public	function	getLoggedInUser( $format = 'XML' );
		public	function	hasAppPermission( $format = 'XML', $uid = FALSE );
	}

	abstract	class	core
	{
		public	$Author		=	'gray';
		public	$Visit		=	'http://www.i-gray.cn';
		public	$Version	=	'1.0.0';

		protected	$v		=	'1.0';
		protected	$resultFormat	=	array( 'XML', 'JSON' );
		protected	$apiKey;
		protected	$secret;
		protected	$restServer;
		protected	$callId;
		protected	$sessionKey;

		public	function	__construct( $apiKey, $secret )
		{
			$this->apiKey	=	$apiKey;
			$this->secret	=	$secret;
			$this->restServer	=	'http://api.xiaonei.com/restserver.do';
			$this->callId		=	$_REQUEST['xn_sig_time'];
			$this->sessionKey	=	$_REQUEST['xn_sig_session_key'];
			$this->apiArrayData	=	array(
				'api_key'	=>	$this->apiKey,
				'call_id'	=>	$this->callId,
				'v'			=>	$this->v
			);
		}

		public	function	addArgToApiArrayData( $attach )
		{
			$this->apiArrayData['sig']			=	md5( core::formatArrayData( ksort( $this->apiArrayData, SORT_STRING ) ) );
			$this->apiArrayData['session_key']	=	urlencode( $this->apiArrayData['session_key'] );

			if( $attach && is_array( $attach ) )
				foreach( $attach as $key => $value )
					$this->apiArrayData[$key] = $value;
		}

		public	function	parse( $method, $attach = false )
		{
			if( !is_array( $method ) )
				$this->apiArrayData['method']	=	$this->api . $method;
			else
				foreach( $method as $key => $value )
					$this->apiArrayData[$key]	=	$value;

			$this->addArgToApiArrayData( $attach );
			return	$this->postApiData( core::formatArrayData( $this->apiArrayData, '&' ) );
		}

		public	function	postApiData ( $array )
		{
			$ch		=	curl_init();
			curl_setopt( $ch, CURLOPT_URL, $this->restServer );
			curl_setopt( $ch, CURLOPT_POST, TRUE );
			curl_setopt( $ch, CURLOPT_POSTFIELDS, $array );
			curl_setopt( $ch, CURLOPT_RETURNTRANSFER, TRUE );
			$result	=	curl_exec( $ch );
			curl_close( $ch );
			return	$result;
		}

		public	function	getResultFormat( $format )
		{
			return	in_array( strtoupper( $format ), $this->resultFormat ) ? strtoupper( $format ) : 'XML';
		}

		static	function	formatArrayData( $array, $glue = '' )
		{
			if( !$array || !is_array( $array ) )
				return;

			$tempArr	=	array();
			foreach( $array as $key => $value )
				$tempArr[]	= "{$key}={$value}";

			return	implode( $glue, $tempArr );
		}
	}

	class	xiaonei	extends	core
	{
		public	$friends;
		public	$users;

		const	USERS_API	=	'xiaonei.users.';
		const	FRIENDS_API	=	'xiaonei.friends.';

		public	function	__construct( $apiKey, $secret )
		{
			parent::__construct( $apiKey, $secret );
			$this->apiArrayData['session_key']	=	$this->sessionKey;
		}

		public	function	friends()
		{
			$this->api	=	self::FRIENDS_API;
			return	$this->friends	=	&new Friends( $this );
		}

		public	function	users()
		{
			$this->api	=	self::USERS_API;
			return	$this->users	=	&new Users( $this );
		}
	}

	class	Users	implements	xnUsers
	{
		private	$users;

		public	function	__construct( $xiaonei )
		{
			$this->users	=	$xiaonei;
		}

		public	function	getInfo( $uids, $format = 'XML', $fields = false, $sessionKey = false )
		{
			$format	=	$this->users->getResultFormat( $format );
			$this->users->apiArrayData['uids']	=	intval( $uids );
			$attach	=	$format == 'XML' && !$fields && !$sessionKey ? FALSE : array(
				'format'	=>	$format,
				'fields'	=>	$fields,
				'session_key'	=>	urlencode( $this->users->apiArrayData['session_key'] )
			);

			return	$this->users->parse( 'getInfo', $attach );
		}

		public	function	getLoggedInUser( $format = 'XML' )
		{
			$format	=	$this->users->getResultFormat( $format );
			$attach	=	$format == 'XML' ? FALSE : array( 'format' => $format );
			return	$this->users->parse( 'getLoggedInUser', $attach );
		}

		public	function	hasAppPermission( $format = 'XML', $extPrem = 'email', $uid = false )
		{
			$format	=	$this->users->getResultFormat( $format );
			$attach	=	$format == 'XML' ? array() : array( 'format' => $format );

			if( !$uid )
				$attach['session_key']	=	urlencode( $this->users->apiArrayData['session_key'] );
			else
				$attach['uid']	=	intval( $uid );

			$this->users->apiArrayData['ext_perm']	=	$extPrem;

			return	$this->users->parse( 'isAppUser', $attach );
		}

		public	function	isAppUser( $format = 'XML', $uid = false )
		{
			$format	=	$this->users->getResultFormat( $format );
			$attach	=	$format == 'XML' ? array() : array( 'format' => $format );

			if( !$uid )
				$attach['session_key']	=	urlencode( $this->users->apiArrayData['session_key'] );
			else
				$attach['uid']	=	intval( $uid );

			return	$this->users->parse( 'isAppUser', $attach );
		}
	}

	class	Friends	implements	xnFriends
	{
		private	$friends;

		public	function	__construct( $xiaonei )
		{
			$this->friends	=	$xiaonei;
		}

		private	function	getCallback( $method, $format, $page, $count )
		{
			$format	=	$this->friends->getResultFormat( $format );
			$attach	=	$format == 'XML' && $page == '0' && $count == '500' ? FALSE : array(
					'format'	=>	$format,
					'page'		=>	$page,
					'count'		=>	$count
			);

			return	$this->friends->parse( $method, $attach );
		}

		public	function	getFriends( $format = 'XML', $page = '0', $count = '500' )
		{
			return	$this->getCallback( 'getFriends', $format, $page, $count );
		}

		public	function	get( $format = 'XML', $page = '0', $count = '500' )
		{
			return	$this->getCallback( 'get', $format, $page, $count );
		}

		public	function	getAppFriends( $format = 'XML', $fields = false )
		{
			$format	=	$this->friends->getResultFormat( $format );
			$attach	=	$format == 'XML' && !$fields ? FALSE : !$fields ? array(
				'format' => $format
				) : array(
				'format' => $format,
				'fields' => $fields
			);

			return	$this->friends->parse( 'getAppFriends', $attach );
		}

		public	function	areFriends( $uids1, $uids2 = false, $format = 'XML' )
		{
			$uids1	=	isset( $uids1 ) && !empty( $uids1 ) ? intval( $uids1 ) : false;
			$uids2	=	!$uids2 ? intval( $_REQUEST['xn_sig_user'] ) : $uids2;

			$format	=	$this->friends->getResultFormat( $format );
			$tempArr		=	array(
				'uids1'		=>	$uids1,
				'uids2'		=>	$uids2,
				'method'	=>	$this->friends->api . 'areFriends'
			);

			$attach	=	$format == 'XML' ? FALSE : array( 'format' => $format );
			return	$this->friends->parse( $tempArr, $attach );
		}
	}
?>